package me.itsoo.elasticbatis.session;

import lombok.Getter;
import me.itsoo.elasticbatis.binding.MapperRegistry;
import me.itsoo.elasticbatis.exceptions.ExceptionFactory;
import me.itsoo.elasticbatis.exceptions.TooManyResultsException;
import me.itsoo.elasticbatis.executor.Executor;
import me.itsoo.elasticbatis.mapping.MappedStatement;

import java.io.IOException;
import java.util.List;

/**
 * SqlSession
 *
 * @author zhangxy4
 * @version 0.0.1
 * @since 2025/4/3
 */
@Getter
public class SqlSession {

    private final Configuration configuration;
    private final Executor executor;

    public SqlSession(Configuration configuration, Executor executor) {
        this.configuration = configuration;
        this.executor = executor;
    }

    public <T> T selectOne(String statement) {
        return this.selectOne(statement, null);
    }

    public <T> T selectOne(String statement, Object parameter) {
        List<T> list = this.selectList(statement, parameter);
        if (list.size() == 1) {
            return list.get(0);
        } else if (list.size() > 1) {
            throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
        } else {
            return null;
        }
    }

    public <T> List<T> selectList(String statement) {
        return this.selectList(statement, null);
    }

    public <T> List<T> selectList(String statement, Object parameter) {
        try {
            MappedStatement ms = configuration.getMappedStatement(statement);
            return executor.query(ms, parameter);
        } catch (IOException e) {
            throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
        }
    }

    public <T> T getMapper(Class<T> type) {
        MapperRegistry mapperRegistry = configuration.getMapperRegistry();
        return mapperRegistry.getMapper(type, this);
    }
}
